/*
 * ========================================================================
 *
 *       Filename:  misc.cpp
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  05/24/2010 05:00:17 PM
 *       Revision:  none
 *       Compiler:  g++
 *
 *         Author:  Alex Avance (aa), aravance@gmail.com
 *        Company:  independent
 *
 * ========================================================================
 *
 * Copyright (C) 2010 Alex Avance
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-
 * 1307, USA.
 *
 * ========================================================================
 */

#include "misc.h"
#include "wx/wx.h"
#include "wx/string.h"
#include "wx/utils.h"

bool LoadDeck ( const wxString &filename, StudyDeck &deck )
{
  wxXmlDocument doc;
  StudyDeck temp;
  if ( !doc.Load( filename ) )
  {
    wxFprintf( stderr,
               _("failed loading \"%s\": could not load file\n"),
               filename.c_str() );
    return false;
  }

  if ( doc.GetRoot()->GetName().Lower() != _("deck") )
  {
    wxFprintf( stderr,
               _("failed loading \"%s\": invalid root: no deck\n"),
               filename.c_str() );
    return false;
  }

  wxXmlNode *child= doc.GetRoot()->GetChildren();
  while ( child )
  {
    if ( child->GetName().Lower() == _("card") )
    {
      wxXmlProperty *property= child->GetProperties();

      bool frontSet, backSet;
      wxString front, back;
      unsigned long right, wrong;

      right= wrong= 0;
      frontSet= backSet= false;

      while ( property )
      {
        wxString name= property->GetName().Lower();
        if ( name == _("front") )
        {
          front= property->GetValue();
          frontSet= true;
        }
        else if ( name == _("back") )
        {
          back= property->GetValue();
          backSet= true;
        }
        else if ( name == _("right") )
          property->GetValue().ToULong( &right );
        else if ( name == _("wrong") )
          property->GetValue().ToULong( &wrong );

        property= property->GetNext();
      }

      if ( !frontSet )
      {
        wxFprintf( stderr,
                  _("failed loading \"%s\": invalid card: no front property\n"),
                  filename.c_str() );
        return false;
      }
      
      if ( !backSet )
      {
        wxFprintf( stderr,
                  _("failed loading \"%s\": invalid card: no back property\n"),
                  filename.c_str() );
        return false;
      }

      temp.Push( StudyDeck::CardT( front, back, right, wrong ) );
    }
    else
      wxFprintf( stderr,
                 _("found invalid child in \"%s\": attempting to continue\n"),
                 filename.c_str() );

    child= child->GetNext();
  }

  deck.Append( temp );
  deck.RecountStats();

  return true;
}

StudyDeck LoadDeck ( const wxString &filename )
{
  StudyDeck deck;

  if ( !LoadDeck( filename, deck ) )
    deck.Clear();

  return deck;
}

bool SaveDeck ( const wxString &filename, const StudyDeck &deck )
{
  StudyDeck temp= deck;
  wxXmlDocument doc;
  wxXmlNode *root= new wxXmlNode( NULL, wxXML_ELEMENT_NODE, _("deck") );
  doc.SetRoot( root );

  temp.Sort();

  if ( temp.Size() > 0 )
  {
    StudyDeck::iterator it= temp.begin(),
                        stop= temp.end();

    wxXmlProperty *properties;
    properties= MakeCardProps( *it );

    root->AddChild( new wxXmlNode( NULL,
                                   wxXML_ELEMENT_NODE,
                                   _("card"),
                                   wxEmptyString,
                                   properties ) );
    wxXmlNode *current= root->GetChildren();

    while ( ++it != stop )
    {
      properties= MakeCardProps( *it );

      current->SetNext( new wxXmlNode( NULL,
                                       wxXML_ELEMENT_NODE,
                                       _("card"),
                                       wxEmptyString,
                                       properties ) );
      current= current->GetNext();
    }
  }

  doc.Save( filename, 1 );

  return true;
}

wxXmlProperty* MakeCardProps ( const StudyCard &card )
{
  wxXmlProperty *prop= new wxXmlProperty( _("front"), card.Front() );
  wxXmlProperty *current= prop;

  current->SetNext( new wxXmlProperty( _("back"), card.Back() ) );
  current= current->GetNext();

  current->SetNext( new wxXmlProperty( _("right"), wxString::Format( _("%d"), card.Right() ) ) );
  current= current->GetNext();

  current->SetNext( new wxXmlProperty( _("wrong"), wxString::Format( _("%d"), card.Wrong() ) ) );
  return prop;
}

